home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / convrtrs / pbmplus / update4.lha / src / extra / ppmtomitsu.c < prev   
Encoding:
C/C++ Source or Header  |  1993-07-08  |  17.4 KB  |  590 lines

  1. /* ppmtomitsu.c - read a portable pixmap and produce output for the
  2. **                Mitsubishi S340-10 Thermo-Sublimation Printer
  3. **                (or the S3410-30 parallel interface)
  4. **
  5. ** Copyright (C) 1992,93 by S.Petra Zeidler
  6. ** Minor modifications by Ingo Wilken:
  7. **  - moved large arrays off the stack into globals (A_SMALLSTACK)
  8. **  - mymalloc() and check_and_rotate() functions for often used
  9. **    code fragments.  Reduces code size by a few KB.
  10. **  - use pm_error() instead of fprints(stderr)
  11. **
  12. ** This software was written for the Max Planck Institut fuer Radioastronomie,
  13. ** Bonn, Germany, Optical Interferometry group
  14. **
  15. ** Permission to use, copy, modify, and distribute this software and its
  16. ** documentation for any purpose and without fee is hereby granted, provided
  17. ** that the above copyright notice appear in all copies and that both that
  18. ** copyright notice and this permission notice appear in supporting
  19. ** documentation.  This software is provided "as is" without express or
  20. ** implied warranty.
  21. */
  22.  
  23. static char SCCSid[] = "@(#)ppmtomitsu.c\t\t1.8\t(SPZ)\t3/31/93\n";
  24. #include "ppm.h"
  25. #include "ppmcmap.h"
  26. #include "pbmplus.h"
  27. #ifdef __STDC__
  28. #include <stdlib.h>
  29. #else
  30. #include <memory.h>
  31. #endif
  32. #include "mitsu.h"
  33.  
  34. #ifdef A_SMALLSTACK
  35. hashinfo colorhashtable[HASHSIZE];
  36. #endif
  37.  
  38.  
  39. #ifdef __STDC__
  40. void main(int argc, char *argv[] )
  41. #else
  42. void main( argc, argv )
  43.     int argc;
  44.     char* argv[];
  45. #endif
  46.     {
  47.     FILE             *ifp;
  48. #ifndef A_SMALLSTACK
  49.     hashinfo         colorhashtable[HASHSIZE];
  50. #endif
  51.     struct hashinfo  *hashrun;
  52.     pixel            *xP;
  53.     int              argn;
  54.         int              dpi300=FALSE;
  55.     int              cols, rows, format, col, row;
  56.     int              sharpness, enlarge, copy, tiny;
  57.     pixval           maxval;
  58.     struct mediasize medias;
  59.     char             media[16];
  60.     char *usage = "[-sharpness <1-4>] [-enlarge <1-3>] [-media <a,a4,as,a4s>] [-copy <1-9>] [-tiny] [-dpi300] [ppmfile]";
  61.  
  62.     ppm_init(&argc, argv);
  63.  
  64.     argn = 1;
  65.     sharpness = 32;
  66.     enlarge   = 1;
  67.     copy      = 1;
  68.     memset(media, '\0', 16);
  69.     tiny      = FALSE;
  70.  
  71.     /* check for flags */
  72.     while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') {
  73.     if (pm_keymatch(argv[argn], "-sharpness", 2)) {
  74.         ++argn;
  75.         if (argn == argc || sscanf(argv[argn], "%d", &sharpness) != 1)
  76.             pm_usage(usage);
  77.         else if (sharpness < 1 || sharpness > 4)
  78.             pm_usage(usage);
  79.         }
  80.     else if (pm_keymatch(argv[argn], "-enlarge", 2)) {
  81.         ++argn;
  82.         if (argn == argc || sscanf(argv[argn], "%d", &enlarge) != 1)
  83.             pm_usage(usage);
  84.         else if (enlarge < 1 || enlarge > 3)
  85.             pm_usage(usage);
  86.         }
  87.     else if (pm_keymatch(argv[argn], "-media", 2)) {
  88.         ++argn;
  89.         if (argn == argc || sscanf(argv[argn], "%15s", media) < 1)
  90.             pm_usage(usage);
  91.         else if (mytoupper(media[0]) != 'A')
  92.             pm_usage(usage);
  93.     }
  94.     else if (pm_keymatch(argv[argn], "-copy", 2)) {
  95.         ++argn;
  96.         if (argn == argc || sscanf(argv[argn], "%d", ©) != 1)
  97.             pm_usage(usage);
  98.         else if (copy < 1 || copy > 9)
  99.             pm_usage(usage);
  100.         }
  101.     else if (pm_keymatch(argv[argn], "-dpi300", 2))
  102.         dpi300 = TRUE;
  103.     else if (pm_keymatch(argv[argn], "-tiny", 2))
  104.         tiny = TRUE;
  105.     else
  106.         pm_usage(usage);
  107.         ++argn;
  108.     }
  109.  
  110.     if (argn < argc) {
  111.         ifp = pm_openr(argv[argn]);
  112.         ++argn;
  113.     }
  114.     else
  115.         ifp = stdin;
  116.  
  117.     if (argn != argc)
  118.         pm_usage(usage);
  119.  
  120.     if (mytoupper(media[0]) == 'A')
  121.         switch (mytoupper(media[1])) {
  122.         case 'S':
  123.             medias = MSize_AS;
  124.             break;
  125.         case '4':
  126.             if(mytoupper(media[2]) == 'S')
  127.                 medias = MSize_A4S;
  128.             else {
  129.                 medias = MSize_A4;
  130.             }
  131.             break;
  132.         default:
  133.             medias = MSize_A;
  134.         }
  135.     else
  136.         medias = MSize_User;
  137.  
  138.         if (dpi300) {
  139.                 medias.maxcols *= 2;
  140.                 medias.maxrows *= 2;
  141.         }
  142.  
  143.     if (tiny) {
  144.         pixel            *pixelrow;
  145.         char             *redrow, *greenrow, *bluerow;
  146.  
  147.         ppm_readppminit(ifp, &cols, &rows, &maxval, &format);
  148.         pixelrow = (pixel *) ppm_allocrow(cols);
  149.         redrow = mymalloc(cols * sizeof(char));
  150.         greenrow = mymalloc(cols * sizeof(char));
  151.         bluerow = mymalloc(cols * sizeof(char));
  152.         lineputinit(cols, rows, sharpness, enlarge, copy, medias);
  153.  
  154.         for ( row = 0; row < rows; ++row ) {
  155.             ppm_readppmrow(ifp, pixelrow, cols, maxval, format);
  156.             switch(PPM_FORMAT_TYPE(format)) {
  157.             /* color */
  158.             case PPM_TYPE:
  159.                 for (col = 0, xP = pixelrow; col < cols; col++, xP++) {
  160.                     /* First red. */
  161.                     redrow[col] = PPM_GETR(*xP);
  162.                     /* Then green. */
  163.                     greenrow[col] = PPM_GETG(*xP);
  164.                     /* And blue. */
  165.                     bluerow[col] = PPM_GETB(*xP);
  166.                 }
  167.                 data(redrow,   cols);
  168.                 data(greenrow, cols);
  169.                 data(bluerow,  cols);
  170.                 break;
  171.             /* grayscale */
  172.             default:
  173.                 for (col = 0, xP = pixelrow; col < cols; col++, xP++)
  174.                     bluerow[col] = PPM_GETB(*xP);
  175.                 data(bluerow, cols);
  176.                 data(bluerow, cols);
  177.                 data(bluerow, cols);
  178.                 break;
  179.             }
  180.         }
  181.         pm_close(ifp);
  182.     }
  183.     else {
  184.         pixel            **pixelpic;
  185.         int              colanz, colval;
  186.         int                 i;
  187.         colorhist_vector table;
  188.  
  189.         ppm_readppminit( ifp, &cols, &rows, &maxval, &format );
  190.         pixelpic = ppm_allocarray( cols, rows );
  191.         for (row = 0; row < rows; row++)
  192.             ppm_readppmrow( ifp, pixelpic[row], cols, maxval, format );
  193.         pm_close(ifp);
  194.  
  195.         /* first check wether we can use the lut transfer */
  196.  
  197.         table = ppm_computecolorhist(pixelpic, cols, rows, MAXLUTCOL+1, &colanz);
  198.         if (table != NULL) {
  199.             for (i=0; i<HASHSIZE; i++) {
  200.                 colorhashtable[i].flag = -1;
  201.                 colorhashtable[i].next = NULL;
  202.             }
  203.  
  204.             /* we can use the lookuptable */
  205.             pm_message("found %d colors - using the lookuptable-method",colanz);
  206.             lookuptableinit(sharpness, enlarge, copy, medias);
  207.             switch(PPM_FORMAT_TYPE(format)) {
  208.             /* color */
  209.             case PPM_TYPE:
  210.                 for (colval=0; colval<colanz; colval++) {
  211.                     cmd('$');
  212.                     datum(colval);
  213.                     datum(PPM_GETR((table[colval]).color));
  214.                     datum(PPM_GETG((table[colval]).color));
  215.                     datum(PPM_GETB((table[colval]).color));
  216.  
  217.                     hashrun = &colorhashtable[myhash((table[colval]).color)];
  218.                     if (hashrun->flag == -1) {
  219.                         hashrun->color = (table[colval]).color;
  220.                         hashrun->flag  = colval;
  221.                     }
  222.                     else {
  223.                         while (hashrun->next != NULL)
  224.                             hashrun = hashrun->next;
  225.                         hashrun->next =
  226.                             (struct hashinfo *) mymalloc(sizeof(struct hashinfo));
  227.                         hashrun = hashrun->next;
  228.                         hashrun->color = (table[colval]).color;
  229.                         hashrun->flag  = colval;
  230.                         hashrun->next  = NULL;
  231.                     }
  232.                 }
  233.                 break;
  234.             /* other */
  235.             default:
  236.                 for (colval=0; colval<colanz; colval++) {
  237.                     cmd('$');
  238.                     datum(colval);
  239.                     datum(PPM_GETB((table[colval]).color));
  240.                     datum(PPM_GETB((table[colval]).color));
  241.                     datum(PPM_GETB((table[colval]).color));
  242.  
  243.                     hashrun = &colorhashtable[myhash((table[colval]).color)];
  244.                     if (hashrun->flag == -1) {
  245.                         hashrun->color = (table[colval]).color;
  246.                         hashrun->flag  = colval;
  247.                     }
  248.                     else {
  249.                         while (hashrun->next != NULL)
  250.                             hashrun = hashrun->next;
  251.                         hashrun->next =
  252.                             (struct hashinfo *) mymalloc(sizeof(struct hashinfo));
  253.                         hashrun = hashrun->next;
  254.                         hashrun->color = (table[colval]).color;
  255.                         hashrun->flag  = colval;
  256.                         hashrun->next  = NULL;
  257.                     }
  258.                 }
  259.             }
  260.             lookuptabledata(cols, rows, enlarge, medias);
  261.             for (row=0; row<rows; row++) {
  262.                 xP = pixelpic[row];
  263.                 for (col=0; col<cols; col++, xP++) {
  264.                     hashrun = &colorhashtable[myhash(*xP)];
  265.                     while (!PPM_EQUAL((hashrun->color), *xP))
  266.                         if (hashrun->next != NULL)
  267.                             hashrun = hashrun->next;
  268.                         else {
  269.                             pm_error("you just found a lethal bug.");
  270.                         }
  271.                     datum(hashrun->flag);
  272.                 }
  273.             }
  274.         }
  275.         else {
  276.         /* $#%@^!& no lut possible, so send the pic as 24bit */
  277.             pm_message("found too many colors for fast lookuptable mode");
  278.             frametransferinit(cols, rows, sharpness, enlarge, copy, medias);
  279.             switch(PPM_FORMAT_TYPE(format)) {
  280.             /* color */
  281.             case PPM_TYPE:
  282.                 COLORDES(RED);
  283.                 DATASTART;                    /* red coming */
  284.                 for (row=0; row<rows; row++) {
  285.                     xP = pixelpic[row];
  286.                     for (col=0; col<cols; col++, xP++)
  287.                         datum(PPM_GETR(*xP));
  288.                 }
  289.                 COLORDES(GREEN);
  290.                 DATASTART;                    /* green coming */
  291.                 for (row=0; row<rows; row++) {
  292.                     xP = pixelpic[row];
  293.                     for (col=0; col<cols; col++, xP++)
  294.                         datum(PPM_GETG(*xP));
  295.                 }
  296.                 COLORDES(BLUE);
  297.                 DATASTART;                    /* blue coming */
  298.                 for (row=0; row<rows; row++) {
  299.                     xP = pixelpic[row];
  300.                     for (col=0; col<cols; col++, xP++)
  301.                         datum(PPM_GETB(*xP));
  302.                 }
  303.                 break;
  304.             /* grayscale */
  305.             default:
  306.                 COLORDES(RED);
  307.                 DATASTART;                    /* red coming */
  308.                 for (row=0; row<rows; row++) {
  309.                     xP = pixelpic[row];
  310.                     for (col=0; col<cols; col++, xP++)
  311.                         datum(PPM_GETB(*xP));
  312.                 }
  313.                 COLORDES(GREEN);
  314.                 DATASTART;                    /* green coming */
  315.                 for (row=0; row<rows; row++) {
  316.                     xP = pixelpic[row];
  317.                     for (col=0; col<cols; col++, xP++)
  318.                         datum(PPM_GETB(*xP));
  319.                 }
  320.                 COLORDES(BLUE);
  321.                 DATASTART;                    /* blue coming */
  322.                 for (row=0; row<rows; row++) {
  323.                     xP = pixelpic[row];
  324.                     for (col=0; col<cols; col++, xP++)
  325.                         datum(PPM_GETB(*xP));
  326.                 }
  327.             }
  328.         }
  329.     }
  330.     PRINTIT;
  331.     exit(0);
  332. }
  333.  
  334. #ifdef __STDC__
  335. static void lineputinit(int cols, int rows,
  336.                         int sharpness, int enlarge, int copy,
  337.                         struct mediasize medias)
  338. #else /*__STDC__*/
  339. static int lineputinit(cols, rows, sharpness, enlarge, copy, medias)
  340.     int cols, rows;
  341.     int sharpness, enlarge, copy;
  342.     struct mediasize medias;
  343. #endif /*__STDC__*/
  344. {
  345.     ONLINE;
  346.     CLRMEM;
  347.     MEDIASIZE(medias);
  348.  
  349.     switch (enlarge) {
  350.     case 2:
  351.         HENLARGE(ENLARGEx2); /* enlarge horizontal */
  352.         VENLARGE(ENLARGEx2); /* enlarge vertical */
  353.         break;
  354.     case 3:
  355.         HENLARGE(ENLARGEx3); /* enlarge horizontal */
  356.         VENLARGE(ENLARGEx3); /* enlarge vertical */
  357.         break;
  358.     default:
  359.         HENLARGE(NOENLARGE); /* enlarge horizontal */
  360.         VENLARGE(NOENLARGE); /* enlarge vertical */
  361.     }
  362.  
  363.     COLREVERSION(DONTREVERTCOLOR);
  364.     NUMCOPY(copy);
  365.  
  366.     HOFFINCH('\000');
  367.     VOFFINCH('\000');
  368.     CENTERING(DONTCENTER);
  369.  
  370.     TRANSFERFORMAT(LINEORDER);
  371.     COLORSYSTEM(RGB);
  372.     GRAYSCALELVL(BIT_8);
  373.  
  374.     switch (sharpness) {          /* sharpness :-) */
  375.     case 0:
  376.         SHARPNESS(SP_NONE);
  377.         break;
  378.     case 1:
  379.         SHARPNESS(SP_LOW);
  380.         break;
  381.     case 2:
  382.         SHARPNESS(SP_MIDLOW);
  383.         break;
  384.     case 3:
  385.         SHARPNESS(SP_MIDHIGH);
  386.         break;
  387.     case 4:
  388.         SHARPNESS(SP_HIGH);
  389.         break;
  390.     default:
  391.         SHARPNESS(SP_USER);
  392.     }
  393.     check_and_rotate(cols, rows, enlarge, medias);
  394.     DATASTART;
  395.     return;
  396. }
  397.  
  398. #ifdef __STDC__
  399. static void lookuptableinit(int sharpness, int enlarge, int copy,
  400.                             struct mediasize medias)
  401. #else /*__STDC__*/
  402. static int lookuptableinit(sharpness, enlarge, copy, medias)
  403.     int sharpness, enlarge, copy;
  404.     struct mediasize medias;
  405. #endif /*__STDC__*/
  406. {
  407.     ONLINE;
  408.     CLRMEM;
  409.     MEDIASIZE(medias);
  410.  
  411.     switch (enlarge) {
  412.     case 2:
  413.         HENLARGE(ENLARGEx2); /* enlarge horizontal */
  414.         VENLARGE(ENLARGEx2); /* enlarge vertical */
  415.         break;
  416.     case 3:
  417.         HENLARGE(ENLARGEx3); /* enlarge horizontal */
  418.         VENLARGE(ENLARGEx3); /* enlarge vertical */
  419.         break;
  420.     default:
  421.         HENLARGE(NOENLARGE); /* enlarge horizontal */
  422.         VENLARGE(NOENLARGE); /* enlarge vertical */
  423.     }
  424.  
  425.     COLREVERSION(DONTREVERTCOLOR);
  426.     NUMCOPY(copy);
  427.  
  428.     HOFFINCH('\000');
  429.     VOFFINCH('\000');
  430.     CENTERING(DONTCENTER);
  431.  
  432.     TRANSFERFORMAT(LOOKUPTABLE);
  433.  
  434.     switch (sharpness) {          /* sharpness :-) */
  435.     case 0:
  436.         SHARPNESS(SP_NONE);
  437.         break;
  438.     case 1:
  439.         SHARPNESS(SP_LOW);
  440.         break;
  441.     case 2:
  442.         SHARPNESS(SP_MIDLOW);
  443.         break;
  444.     case 3:
  445.         SHARPNESS(SP_MIDHIGH);
  446.         break;
  447.     case 4:
  448.         SHARPNESS(SP_HIGH);
  449.         break;
  450.     default:
  451.         SHARPNESS(SP_USER);
  452.     }
  453.  
  454.     LOADLOOKUPTABLE;
  455.     return;
  456. }
  457.  
  458. #ifdef __STDC__
  459. static void lookuptabledata(int cols, int rows, int enlarge,
  460.                                                         struct mediasize medias)
  461. #else /*__STDC__*/
  462. static int lookuptabledata(cols, rows, enlarge, medias)
  463.     int   rows, cols;
  464.     int   enlarge;
  465.     struct mediasize medias;
  466. #endif /*__STDC__*/
  467. {
  468.     DONELOOKUPTABLE;
  469.     check_and_rotate(cols, rows, enlarge, medias);
  470.     DATASTART;
  471.     return;
  472. }
  473.  
  474. #ifdef __STDC__
  475. static void frametransferinit(int cols, int rows, int sharpness,
  476.                               int enlarge, int copy, struct mediasize medias)
  477. #else
  478. static int frametransferinit(cols, rows, sharpness, enlarge, copy, medias)
  479.  
  480.     int     rows, cols;
  481.     int     sharpness, enlarge, copy;
  482.     struct mediasize medias;
  483. #endif
  484. {
  485.     ONLINE;
  486.     CLRMEM;
  487.     MEDIASIZE(medias);
  488.  
  489.     switch (enlarge) {
  490.     case 2:
  491.         HENLARGE(ENLARGEx2); /* enlarge horizontal */
  492.         VENLARGE(ENLARGEx2); /* enlarge vertical */
  493.         break;
  494.     case 3:
  495.         HENLARGE(ENLARGEx3); /* enlarge horizontal */
  496.         VENLARGE(ENLARGEx3); /* enlarge vertical */
  497.         break;
  498.     default:
  499.         HENLARGE(NOENLARGE); /* enlarge horizontal */
  500.         VENLARGE(NOENLARGE); /* enlarge vertical */
  501.     }
  502.  
  503.     COLREVERSION(DONTREVERTCOLOR);
  504.     NUMCOPY(copy);
  505.  
  506.     HOFFINCH('\000');
  507.     VOFFINCH('\000');
  508.     CENTERING(DONTCENTER);
  509.  
  510.     TRANSFERFORMAT(FRAMEORDER);
  511.     COLORSYSTEM(RGB);
  512.     GRAYSCALELVL(BIT_8);
  513.  
  514.     switch (sharpness) {          /* sharpness :-) */
  515.     case 0:
  516.         SHARPNESS(SP_NONE);
  517.         break;
  518.     case 1:
  519.         SHARPNESS(SP_LOW);
  520.         break;
  521.     case 2:
  522.         SHARPNESS(SP_MIDLOW);
  523.         break;
  524.     case 3:
  525.         SHARPNESS(SP_MIDHIGH);
  526.         break;
  527.     case 4:
  528.         SHARPNESS(SP_HIGH);
  529.         break;
  530.     default:
  531.         SHARPNESS(SP_USER);
  532.     }
  533.     check_and_rotate(cols, rows, enlarge, medias);
  534.     return;
  535. }
  536.  
  537.  
  538. #ifdef __STDC__
  539. static void *
  540. mymalloc(long bytes)
  541. #else
  542. static char *
  543. mymalloc(bytes)
  544.     long bytes;
  545. #endif
  546. {
  547.     void *mem;
  548.  
  549.     mem = malloc(bytes);
  550.     if( mem == NULL )
  551.         pm_error("out of memory allocating %d bytes", bytes);
  552.  
  553.     return mem;
  554. }
  555.  
  556.  
  557. #ifdef __STDC__
  558. static void
  559. check_and_rotate(int cols, int rows, int enlarge, struct mediasize medias)
  560. #else
  561. static void
  562. check_and_rotate(cols, rows, enlarge, medias)
  563.     int cols, rows, enlarge;
  564.     struct mediasize medias;
  565. #endif
  566. {
  567.     if (cols > rows) {
  568.         ROTATEIMG(DOROTATE);                        /* rotate image */
  569.         if (enlarge*rows > medias.maxcols || enlarge*cols > medias.maxrows) {
  570.             pm_error("Image too large, MaxPixels = %d x %d", medias.maxrows, medias.maxcols);
  571.         }
  572.         HPIXELS(cols);
  573.         VPIXELS(rows);
  574.         HPIXELSOFF((medias.maxcols/enlarge - rows)/2);
  575.         VPIXELSOFF((medias.maxrows/enlarge - cols)/2);
  576.         pm_message("rotating image for output");
  577.     }
  578.     else {
  579.         ROTATEIMG(DONTROTATE);
  580.         if (enlarge*rows > medias.maxrows || enlarge*cols > medias.maxcols) {
  581.             pm_error("Image too large, MaxPixels = %d x %d", medias.maxrows, medias.maxcols);
  582.         }
  583.         HPIXELS(cols);
  584.         VPIXELS(rows);
  585.         HPIXELSOFF((medias.maxcols/enlarge - cols)/2);
  586.         VPIXELSOFF((medias.maxrows/enlarge - rows)/2);
  587.     }
  588. }
  589.  
  590.